import json
import uuid
import os
from threading import Thread

from django.contrib import auth
from django.contrib import messages
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.shortcuts import render,resolve_url, redirect, get_object_or_404
from django.http import HttpResponse, HttpRequest
from django.http.response import JsonResponse,HttpResponseBadRequest,FileResponse
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from django.core.mail import send_mail
from email_validator import EmailNotValidError,validate_email as ValidateEmail
from django.contrib.auth.tokens import default_token_generator
from django.views import View
from authentication.froms import RegistrationForm
from django.contrib.sites.shortcuts import get_current_site
from django.utils.decorators import method_decorator
from .models import UserProfile
from .urils import generate_captcha



# Create your views here.
def register(request: HttpRequest):
    if request.method == 'GET':
        return render(request, 'authentication/register.html')
    else:
        from_obj = RegistrationForm(request.POST)
        if from_obj.is_valid():
            user = User(username=from_obj.cleaned_data['username'], email=from_obj.cleaned_data['email'],)
            user.set_password(from_obj.cleaned_data['password'])
            user.is_active = False
            user.save()
            # 发送邮件
            content = """
                请点击以下链接激活账号:
                http://127.0.0.1:8000/authentication/verify-account/{0}
            """.format(from_obj.cleaned_data['username'])
            t = Thread(target=send_mail, args=[
                '激活邮件[鱿鱼账本]',
                content,
                settings.EMAIL_HOST_USER,
                [from_obj.cleaned_data['email'],],
                False,
            ])
            t.start()
            return HttpResponse('请去邮箱激活账号')
        else:
            print(from_obj.errors)
            context = {
                'form_obj': from_obj,
                'values': request.POST,
            }
            return render(request, 'authentication/register.html', context=context)




class LogoutView(View):
    def get(self, request):
        return render(request, 'authentication/login.html')
    def post(self, request):
        context = {
            'values': request.POST,
        }
        username = request.POST.get('username')
        password = request.POST.get('password')
        verify_code = request.POST.get('verify')
        print(username, password, request.session.get('verify'))
        if verify_code != request.session.get('verify'):
            messages.error(request, '验证码错误')
            return render(request, 'authentication/login.html', context=context)
        if not User.objects.filter(username=username).exists():
            messages.error(request, '用户名不存在')
            return render(request, 'authentication/login.html', context=context)

        user = User.objects.get(username=username)
        if not user.check_password(password):
            messages.error(request, '密码不正确')
            return render(request, 'authentication/login.html', context=context)
        else:
            auth.login(request, user)
            return redirect(to='expense')


def logout(request: HttpRequest):
    auth.logout(request)
    messages.success(request, '退出成功')
    return redirect(to='login')


class validateUsername(View):
    def post(self, request):
        data = json.loads(request.body)
        print(data)
        username = data['username']
        if not username.strip():
            return JsonResponse({'status': 'error', 'msg': '用户名不能为空'}, status=400)
        if User.objects.filter(username=username.strip()).exists():
            return JsonResponse({'status': 'error', 'msg': '用户名已存在'}, status=400)
        else:
            return JsonResponse({'status': 'success', 'msg': 'OK'}, status=200)

@csrf_exempt
def validate_email(request):
    if request.method == 'POST':
        """
        """
        data = json.loads(request.body)
        print(data)
        email = data['email']
        if not email.strip():
            return JsonResponse({'status':'error','msg': '邮箱不能为空'}, status=400)

        # 邮箱的格式
        try:
            ValidateEmail(email, check_deliverability=True)
        except EmailNotValidError as e:
            return JsonResponse({'status':'error','msg':'邮箱格式错误'}, status=400)

        if User.objects.filter(email=email.strip()).exists():
            return JsonResponse({'status':'error','msg': '邮箱已存在'}, status=400)
        else:
            return JsonResponse({'status':'success','msg': 'OK'}, status=200)


def verify_account(request,username):
    u = get_object_or_404(User, username=username, is_active=False)
    u.is_active = True
    u.save()
    messages.success(request, '账号激活成功')
    return redirect(to='login')

def forget_password(request):
    if request.method == 'GET':
        return render(request, 'authentication/forget-password.html')
    else:
        email = request.POST.get('email')
        if not User.objects.filter(email=email).exists():
            context = {
                'error': '邮箱不存在',
                'email': email
            }
            return render(request, 'authentication/forget-password.html', context=context)

        user = User.objects.get(email=email)
        current_site = get_current_site(request)
        token = default_token_generator.make_token(user)
        link = 'http://' + current_site.domain + resolve_url('reset-password', user.pk, token)

        # 发送邮件
        content = """
               请点击以下链接激活账号:
               {0}
        """.format(link)
        t = Thread(target=send_mail, args=[
            '找回密码[鱿鱼账本]',
            content,
            settings.EMAIL_HOST_USER,
            [user.email, ],
            False,
        ])
        t.start()
        return HttpResponse('请去邮箱重置密码')

def reset_password(request,uid,token):
    if request.method == 'GET':
        user = get_object_or_404(User, pk=uid)
        if not default_token_generator.check_token(user, token):
            return HttpResponseBadRequest('链接已失效')

        messages.info(request, f'Hello:{user.username},请重置您的新密码')
        return render(request, 'authentication/reset-password.html')

    else:
        user = get_object_or_404(User, pk=uid)
        if not default_token_generator.check_token(user, token):
            return HttpResponseBadRequest('链接已失效')

        password = request.POST.get('password')
        re_password = request.POST.get('re_password')
        if password != re_password:
            messages.error(request, '两次密码不一致')
            return render(request, 'authentication/reset-password.html')
        # todo 密码强度校验
        user.set_password(password)
        user.save()
        messages.success(request, '密码重置成功')
        return redirect(to='login')
@method_decorator(login_required(login_url='login'), name='get')
@method_decorator(login_required(login_url='login'), name='post')
class ChangePasswordView(View):

    def get(self, request):
        return render(request, 'authentication/change-password.html')


    def post(self, request):
        old_password = request.POST.get('old-password')
        if not request.user.check_password(old_password):
            messages.error(request, '旧密码不正确')
            return render(request, 'authentication/change-password.html')
        new_password = request.POST.get('new-password')
        re_password = request.POST.get('re-password')
        if len(new_password) < 6:
            messages.error(request, '密码长度不能小于6位')
            return render(request, 'authentication/change-password.html')
        if new_password != re_password:
            messages.error(request, '两次密码不一致')
            return render(request, 'authentication/change-password.html')
        request.user.set_password(new_password)
        request.user.save()
        messages.success(request, '密码修改成功')
        return render(request, 'authentication/change-password.html')


@method_decorator(login_required(login_url='login'), name='get')
@method_decorator(login_required(login_url='login'), name='post')
class UploadAvatarView(View):
    def get(self, request):
        try:
            profile = request.user.userprofile
            print(profile.avatar)
        except UserProfile.DoesNotExist:
            UserProfile.objects.create(user=request.user)
        return render(request, 'authentication/upload-avatar.html')

    def post(self, request):
        avatar = request.FILES.get('avatar')
        if not avatar:
            messages.error(request, '请选择要上传的头像文件')
            return render(request, 'authentication/upload-avatar.html')

        # 获取文件扩展名
        ext = os.path.splitext(avatar.name)[1]
        # 生成随机文件名
        filename = f"{uuid.uuid4().hex}{ext}"

        profile, created = UserProfile.objects.get_or_create(user=request.user)
        profile.avatar.save(filename, avatar)
        profile.save()

        messages.success(request, '头像上传成功')
        return redirect('upload-avatar')


def get_verify_code(request):
    verify_code, buff = generate_captcha()
    request.session['verify'] = verify_code
    return FileResponse(buff, filename='verify.gif', headers={'Content-Type':'image/gif'})




